#ifndef SGU_TSTORAGE_
#define SGU_TSTORAGE_H

SGU_NS_BEGIN


class TIStorage : public NoCopy
{
	public:
	TIStorage(const ConstSegment &);
	virtual ~TIStorage();

	enum Cmd {BEGIN,END,ABORT};

	TIStorage & operator >> (Serializable &);

	TIStorage & operator >> (char &);
	TIStorage & operator >> (unsigned char &);
	TIStorage & operator >> (short &);
	TIStorage & operator >> (unsigned short &);
	TIStorage & operator >> (int &);
	TIStorage & operator >> (unsigned int &);
	TIStorage & operator >> (long &);
	TIStorage & operator >> (unsigned long &);

    TIStorage & operator >> (double &);
	TIStorage & operator >> (bool &);
	TIStorage & operator >> (std::string &);
	TIStorage & operator >> (std::wstring &);

	TIStorage & operator >> (const char *);
	TIStorage & operator >> (Cmd);
	
	void checkSignature();
			
	
	protected:
	char read();
	char peek();
	void eatWhite();
	
	
	private:
	const ConstSegment & _data;
	size_t _ptr;
	std::vector<char> _nesting;
	char qread();
	char qpeek();
	const char * queryPtr() const;
	void qskip(size_t);
	void qskip();

};


class TOStorage : public NoCopy
{
	public:
	TOStorage(DynamicSegment &);
	virtual ~TOStorage();

	enum Cmd {POP,NL,BLANK,BEGIN,END};
	enum Radix {DEC,HEX,BIN};
	
	TOStorage & operator << (const Serializable &);

	TOStorage & operator << (char);
	TOStorage & operator << (unsigned char);
	TOStorage & operator << (short);
	TOStorage & operator << (unsigned short);
	TOStorage & operator << (int);
	TOStorage & operator << (unsigned int);
	TOStorage & operator << (long);
	TOStorage & operator << (unsigned long);	
	
	TOStorage & operator << (double);
	TOStorage & operator << (bool);
	TOStorage & operator << (const std::string &);
	TOStorage & operator << (const std::wstring &);

	TOStorage & operator << (const char *);
	TOStorage & operator << (Cmd);
	TOStorage & operator << (Radix);

	void writeSignature();

	protected:
	void write(char);
	void write(const char *);

	#ifdef SGU_DEBUG
	void throws(const char * exc, const char * file, int line);
	#else
	void throws(const char *);
	#endif	

	private:
	DynamicSegment & _data;
	size_t _ptr;
	std::stack<Radix> _radix;
	std::stack<char> _nesting;
	bool _needspaceafter;
	bool _newline;
	bool _error;
	
	void qwrite(char);
	void qwrite(const char *);	
	char * queryPtr() const;
	void qskip(size_t);
	void qreserve(size_t);
	void indent();
};

SGU_NS_END

#endif
